package com.macro.mall.es.service.impl;

import com.macro.mall.common.api.CommonResult;
import com.macro.mall.common.dto.EsIndexDto;
import com.macro.mall.es.service.EsIndexService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.*;

import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;
/**
 * es索引Service
 */
@Service
@Slf4j
public class EsIndexServiceImpl implements EsIndexService {
    @Resource
    private RestHighLevelClient restHighLevelClient;

    /**
     * 添加索引
     * @param esIndexDto
     * @return
     */
    @Override
    public CommonResult createProductIndex(EsIndexDto esIndexDto) {
        CommonResult commonResult = searchIndexChecker(esIndexDto.getIndexName());
        Boolean data = (Boolean) commonResult.getData();
        if (data!=null){
            throw new RuntimeException("索引存在");
        }
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(esIndexDto.getIndexName());
        if (esIndexDto.getIndexMappings() != null) {
            createIndexRequest.mapping(esIndexDto.getIndexMappings(),XContentType.JSON);
        }
        if (esIndexDto.getIndexSetting() != null) {
            createIndexRequest.settings(esIndexDto.getIndexSetting(),XContentType.JSON);
        }
        try {
            restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("创建索引的方法出现异常：参数：{}，信息：{}", esIndexDto, e.getMessage());
            throw new RuntimeException("es异常请正在修复");
        }
        return CommonResult.success("添加索引成功");
    }

    /**
     * 查询索引
     * @param indexName
     * @return
     */
    @Override
    public CommonResult<Map<String, Object>> searchProductIndex(String indexName) {
        CommonResult commonResult = searchIndexChecker(indexName);
        Boolean data = (Boolean) commonResult.getData();
        if (!data){
            throw new RuntimeException("索引不存在");
        }
        GetMappingsRequest getMappingsRequest = new GetMappingsRequest();
        getMappingsRequest.indices(indexName);
        try {
            GetMappingsResponse mapping = restHighLevelClient.indices().getMapping(getMappingsRequest, RequestOptions.DEFAULT);
            Map<String, Object> sourceAsMap = mapping.mappings().get(indexName).getSourceAsMap();
            return CommonResult.success(sourceAsMap);
        } catch (IOException e) {
            log.error("查询索引出现错误：参数：{}，错误信息：{}",indexName,e.getMessage());
            throw new RuntimeException();
        }

    }

    /**
     * 校验索引
     * @param indexName
     * @return
     */
    @Override
    public CommonResult searchIndexChecker(String indexName) {
        GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
        try {
            restHighLevelClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
            // 索引存在
            return CommonResult.success("true");
        } catch (ElasticsearchException e) {
            if (e.status() == RestStatus.NOT_FOUND) {
                // 索引不存在
                return CommonResult.failed("false");
            }
            // 其他 Elasticsearch 相关的异常，可以根据需要记录日志或抛出更具体的异常
            throw new RuntimeException("检查索引是否存在时发生 Elasticsearch 异常", e);
        } catch (IOException e) {
            // 处理其他类型的 IO 异常，如网络问题、连接超时等
            throw new RuntimeException("检查索引是否存在时发生 IO 异常", e);
        }
    }

    /**
     * 修改索引
     * @param esIndexDto
     * @return
     */
    @Override
    public CommonResult updateIndexProduct(EsIndexDto esIndexDto) {
        if (esIndexDto.getIndexSetting() != null) {
            try {
                UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(esIndexDto.getIndexName());
                updateSettingsRequest.settings(esIndexDto.getIndexSetting(),XContentType.JSON);
                restHighLevelClient.indices().putSettings(updateSettingsRequest,RequestOptions.DEFAULT);
            } catch (IOException e) {
                log.error("更新索引设置时发生异常：索引名：{}，设置：{}，异常信息：{}", esIndexDto.getIndexName(), esIndexDto.getIndexSetting(), e.getMessage());
                return CommonResult.failed("更新索引设置时发生异常");
            }
        }
        if (esIndexDto.getIndexMappings()!=null){
            try {
                PutMappingRequest putMappingRequest = new PutMappingRequest(esIndexDto.getIndexName());
                putMappingRequest.source(esIndexDto.getIndexMappings(),XContentType.JSON);
                restHighLevelClient.indices().putMapping(putMappingRequest,RequestOptions.DEFAULT);
            } catch (IOException e) {
                log.error("更新索引映射时发生异常：索引名：{}，映射：{}，异常信息：{}", esIndexDto.getIndexName(), esIndexDto.getIndexMappings(), e.getMessage());
                return CommonResult.failed("更新索引映射时发生异常");
            }
        }
        return CommonResult.success("索引更新成功");
    }
    /**
     * 删除索引
     * @param indexName
     * @return
     */
    @Override
    public CommonResult delProductIndex(String indexName) {
        CommonResult commonResult = searchIndexChecker(indexName);
        Boolean data = (Boolean) commonResult.getData();
        if (!data){
            throw new RuntimeException("索引不存在");
        }
        try {
            DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
            AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
            boolean acknowledged = delete.isAcknowledged();
            if (acknowledged){
                return CommonResult.success("删除成功");
            }else {
                return CommonResult.success("删除失败");
            }
        } catch (IOException e) {
            log.error("更新索引映射时发生异常：索引名：{},异常信息：{}",indexName, e.getMessage());
            throw new RuntimeException(e);
        }
    }
}
